<template>
    <div class="chat">
        <header class="header">
            <h1>世界无产阶级革命交流论坛</h1>
            <h3>在线人数: {{ state.online }}</h3>
        </header>

        <main class="main" ref="mainRef" v-loading="syncLoading">
            <div class="sync-message" v-if="showSyncMore" >
                    <div class="sync-tips"><a class="sync-tips" href="javaScript:;" @click="syncMore">
                        <i class="el-icon-refresh"/> 查看更多消息</a></div>
            </div>
            <div class="message-item"
                :class="{ 'user': item.uuid === user.uuid && !item.wellcom, 'wellcom': item.wellcom }"
                v-for="item in data" :key="item.uuid">
                <!-- 欢迎入群 -->
                <template v-if="item.wellcom">
                    <div class="wellcom-tips">{{ item.wellcom }}</div>
                </template>
                <!-- 群聊信息 -->
                <template v-else>
                    <el-avatar v-if="item.uuid !== user.uuid" :size="50" :src="item.avatar" />
                    <div class="message-info">
                        <p class="name">{{ item.name }}</p>
                        <div class="display" v-html="formatMessage(item.message, item.image)">
                        </div>
                        <p class="date">{{ item.date }}</p>
                    </div>
                    <el-upload v-if="item.uuid === user.uuid" ref="upload" class="upload-demo" :show-file-list="false"
                        :on-change="onFileChange" :limit="1" :auto-upload="false">
                        <template #trigger>
                            <el-avatar :size="50" :src="item.avatar" />
                        </template></el-upload>
                </template>
            </div>
        </main>

        <footer class="footer">
            <el-popover popper-class="emo_popover" placement="top" :width="900"  v-model:visible="visible"
                trigger="click">
                <img class="emo_item pointer" v-for="item in emotions" :key="item.title" @click="chooseEmo(item)"
                    :src="item.emot" />
                <template #reference>
                    <img class="pointer" :src="emotions[range_num].emot" />
                </template></el-popover>

            <el-input v-model="message" type="textarea" placeholder="这里不是无人区，请友好交流 (゜-゜)つロ 干杯" :autosize="{ maxRows: 2 }" @keydown.enter.native="sendAction"/>
            <el-button v-show="message" type="primary" round @click="sendAction">发送</el-button>
            <el-upload ref="upload" class="upload-demo" :show-file-list="false"
                       :on-change="onUploadImage"  :auto-upload="false">
                <template #trigger>
                    <img style="width: 40px;margin-left: 5px;top: 4px" src="/image.png" />
                </template>
            </el-upload>

        </footer>
    </div>
</template>

<script setup lang='ts'>
import {nextTick, onBeforeUnmount, ref} from 'vue';
import { dayjs } from 'element-plus';
import type { UploadInstance, UploadFile } from 'element-plus'
import { useUser } from '@/stores/user';
import type { Ueser } from '@/stores/user'
import useData from './composable/useData';
import useEmotion from './composable/useEmotion';
import useMessage from './composable/useMessage';

let avatar = 'https://img1.baidu.com/it/u=4035421571,4160111639&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500';

const visible = ref(false);
const mainRef = ref(null);
const upload = ref<UploadInstance>()
let syncLoading = false

const { emotions, emotMap } = useEmotion();
const { message, chooseEmo, formatMessage } = useMessage(visible, emotMap);
const state = useUser();
const user: Ueser = state.user;
const {data,allMsgCount} = useData(user, mainRef);

const getRangeNum = (n: number, m: number) => {
    return Math.floor(Math.random() * (n - m) + m)
}


const range_num = getRangeNum(0,75)
// 避免用户在当前页面刷新
if (user.name) window.socket.emit("register", user.name);

onBeforeUnmount(() => {
    // 用户离开
    window.socket.emit('leave', user)
});
// 同步消息
const syncMore = () => {
    window.socket.emit("sync", user, 5, data.value.length);
    syncLoading = true
    tryShowSyncMore();
}

let showSyncMore = true;
const tryShowSyncMore = () => {
    window.socket.emit("syncCount");
    window.socket.on("syncCount", (allCount: Number) => {
        console.log("data.value.length",data.value.length," allCount:",allCount)
        showSyncMore = allCount > data.value.length+1;
    });
    syncLoading=false;

    setTimeout(function() {
        const el: HTMLElement = mainRef.value!;
        el.scrollTop = 0;
    }, 200);


}

// 发送消息
const sendAction = () => {
    const info = {
        uuid: user.uuid,
        name: user.name,
        message: message.value,
        image:NaN,
        date: dayjs().format("YYYY-MM-DD HH:mm:ss"),
        avatar
    };

    data.value.push(info);
    message.value = '';

    window.socket.emit('chat', info);
}

// file 转 base64
const fileToBase64Async = (file: File) => {
    return new Promise((resolve, reject) => {
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (e) => {
            console.log(" reader.onload ")
            resolve(e.target?.result);
        };
        reader.onerror = () => {
            console.log("reader.onerror")
            resolve('');
        }
    });
}

// 处理头像变更
const onFileChange = async (uploadFile: UploadFile) => {
    const data: any = await fileToBase64Async((uploadFile.raw as File));
    if (data) {
        avatar = user.avatar = data;
        window.socket.emit('avatar', user);
    }
}
//
const onUploadImage = async (uploadFile: UploadFile) => {
    const image: any = await fileToBase64Async((uploadFile.raw as File));
        const info = {
            uuid: user.uuid,
            name: user.name,
            message: "#image#",
            image:image,
            date: dayjs().format("YYYY-MM-DD HH:mm:ss"),
            avatar
        };

        data.value.push(info);

        window.socket.emit('chat', info);

}

</script>

<style lang="scss">
.chat {
    height: 100vh;
    width: 100vw;
    display: flex;
    flex-direction: column;

    .header,
    footer {
        padding: 2px 5px;
        min-height: 10vh;
        display: flex;
        justify-content: center;
        align-items: center;
        color: aliceblue;
        background-image: linear-gradient(120deg, #a1c4fd 0%, #c2e9fb 100%);
    }

    .header {
        flex-direction: column;
    }

    .main {
        flex: 1;
        overflow-y: scroll;
        background-color: rgba(30, 128, 255, .05);
        .sync-message{
            .sync-tips{
                text-align: center;
                justify-content: center;
                color: #f59a9a;
                text-decoration:none;
            }
        }

        .message-item {
            padding: 0 5px;
            margin: 20px 0;
            display: flex;
            align-items: flex-start;

            .message-info {
                margin-left: 10px;
                width: 80vw;
            }

            .name {
                max-width: 80vw;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                margin-bottom: 5px;
            }

            .date {
                font-size: 12px;
                color: #989fb1;
            }

            .display {
                display: inline-block;
                background-color: #fff;
                border-radius: 5px;
                min-height: 30px;
                max-width: 80vw;
                word-break: break-word;
                padding: 5px;
                box-shadow: 0px 0px 5px rgba($color: #000000, $alpha: 0.3);
            }

            .emot_msg {
                width: 50px;
                height: 50px;
                cursor: pointer;
                vertical-align: bottom;
            }

            .upload_image {
                max-width: 300px;
                max-height: 300px;
                cursor: pointer;
                vertical-align: bottom;
            }

            &.wellcom {
                text-align: center;
                justify-content: center;
                color: #989fb1;
            }

            &.user {
                text-align: right;
                justify-content: flex-end;

                .name {
                    text-align: right;
                }

                .message-info {
                    margin-left: 0;
                    margin-right: 10px;
                }
            }
        }
    }

    .footer {
        min-height: 10vh;

        .el-textarea {
            flex: 1;
            margin: 0 5px;
        }
    }
}

.pointer {
    cursor: pointer;
}

.emo_popover {
    max-height: 500px;
    overflow:scroll;

    .emo_item {
        width: 40px;
        height: 40px;
        margin: 5px;
    }
}
</style>
